﻿using CsvHelper;
using Python.Runtime;
using System.Globalization;

namespace PythonnetButterworth
{
    public class Program
    {
        const string PathToPythonDir = "D:\\Python311";
        const string DllOfPython = "python311.dll";

        static void Main(string[] args)
        {
            // Butter-worth低通滤波
            ButterworthLowpass();
        }
        /// <summary>
        /// Butter-worth低通滤波
        /// </summary>
        static void ButterworthLowpass(int fs = 250, double filterCutoff = 50, int axis = 0, int order = 8)
        {
            try
            {
                Runtime.PythonDLL = Path.Combine(PathToPythonDir, DllOfPython);

                PythonEngine.Initialize();
                using (Py.GIL())
                {
                    dynamic pd = Py.Import("pandas");
                    dynamic np = Py.Import("numpy");
                    dynamic plt = Py.Import("matplotlib.pyplot");
                    dynamic signal = Py.Import("scipy.signal");

                    dynamic data = pd.read_csv("clean_data_row.csv");
                    int listLength = data.__len__();
                    double wn = filterCutoff / (fs / 2.0);

                    PyTuple baTuple = signal.butter(order, wn, "low");
                    dynamic b = baTuple[0];
                    dynamic a = baTuple[1];
                    PyObject calcData = signal.filtfilt(b, a, data, axis: axis, padlen: listLength - 1);
                    int calcLength = data.__len__();
                    double[][] calcDataArray = calcData.As<dynamic[]>().Select(s => (double[])s.As<double[]>()).ToArray();

                    plt.figure(figsize: new dynamic[] { 12, 6 });

                    // 原始数据
                    plt.subplot(1, 2, 1);
                    plt.plot(np.arange(listLength), data);
                    plt.title("Original Datas");

                    // 低通滤波
                    plt.subplot(1, 2, 2);
                    plt.plot(np.arange(calcLength), calcData);
                    plt.title("Butterworth Lowpas Datas");

                    // 布局调整，防止重叠
                    plt.tight_layout();
                    // 显示图表
                    plt.show();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("报错了：" + e.Message + "\r\n" + e.StackTrace);
            }
        }

        /// <summary>
        /// 读取CSV数据
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <returns>文件中数据集合，都是double类型</returns>
        static List<double[]> ReadCsvWithCsvHelper(string filePath)
        {
            using (var reader = new StreamReader(filePath))
            using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
            {
                var result = new List<double[]>();
                // 如果你的CSV文件有标题行，可以调用ReadHeader来读取它们
                csv.Read();
                csv.ReadHeader();
                while (csv.Read())
                {
                    result.Add(new double[] {
                    csv.GetField<double>(0),
                    csv.GetField<double>(1),
                    csv.GetField<double>(2),
                    csv.GetField<double>(3),
                    csv.GetField<double>(4),
                    csv.GetField<double>(5),
                });
                }
                return result;
            }
        }
    }
}
